
package com.cortex.pineapple.view;

import java.text.SimpleDateFormat;
import java.util.List;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.MeasureSpec;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.cortex.pineapple.R;
import com.cortex.pineapple.adapters.Header;
import com.cortex.pineapple.adapters.ItemList;
import com.cortex.pineapple.adapters.ItemListAdapter;
import com.cortex.pineapple.adapters.ItemListAdapter.OnDragItemListener;
import com.cortex.pineapple.adapters.RegularZoomHistoryAdapter;
import com.cortex.pineapple.adapters.ZoomInHistoryAdapter;
import com.cortex.pineapple.adapters.ZoomOutHistoryAdapter;
import com.cortex.pineapple.database.SeasonQuerySearch;
import com.cortex.pineapple.database.VisitLink;
import com.cortex.pineapple.utilities.MessagesLog;

public class TimeLine extends LinearLayout {

	private TextView dateSeason,dateQuery;
	private CortexTextView query;
	private CortexListView regularTimeLine,zoomOutTimeLine,zoomInTimeLine;
	private View line;
	private RelativeLayout containerTimeLine;
	private SeasonQuerySearch lastSeason;
	private OnClickVisitLink onClickVisitLink;
	private OnFinishedScrollListener onFinishedScrollListener;
	private View header;
	private SimpleDateFormat dateFormater = (SimpleDateFormat) SimpleDateFormat.getDateInstance(SimpleDateFormat.MEDIUM);
	private SimpleDateFormat timeFormater = (SimpleDateFormat) SimpleDateFormat.getTimeInstance(SimpleDateFormat.SHORT);
	private OnDragItemListener onDragRowListener;
	private int savedListTop,savedPosition = -1; 
	private LEVEL_ZOOM level = null;
	private boolean isZoomMode;
	private LinearLayout containerHeader;



	public TimeLine(Context context) {
		super(context);
		init();
	}
	public TimeLine(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	public TimeLine(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();
	}
	private void init(){
		LayoutInflater.from(getContext()).inflate(R.layout.view_time_line, this);
		containerTimeLine = (RelativeLayout)findViewById(R.id.containerTimeLine);
		regularTimeLine = (CortexListView)findViewById(R.id.regularTimeLine);
		zoomOutTimeLine = (CortexListView)findViewById(R.id.zoomOutTimeLine);
		zoomInTimeLine = (CortexListView)findViewById(R.id.zoomInTimeLine);
		dateSeason = (TextView)findViewById(R.id.dateSeason);
		dateQuery = (TextView)findViewById(R.id.dateQuery);
		query = (CortexTextView)findViewById(R.id.query);
		line = findViewById(R.id.line);
		header = findViewById(R.id.header);
		header.setBackgroundColor(getResources().getColor(R.color.time_line_background));
		containerHeader = (LinearLayout)findViewById(R.id.containerHeader);

		initListeners();
	}
	private void initListeners(){
		TimeLineListeners timeLineListeners = new TimeLineListeners();
		regularTimeLine.setOnScrollListener(timeLineListeners);
		regularTimeLine.setOnItemClickListener(timeLineListeners);
		regularTimeLine.setOnItemLongClickListener(timeLineListeners);
		regularTimeLine.setOnTouchListener(timeLineListeners);

		zoomOutTimeLine.setOnScrollListener(timeLineListeners);
		zoomOutTimeLine.setOnItemClickListener(timeLineListeners);
		zoomOutTimeLine.setOnItemLongClickListener(timeLineListeners);
		zoomOutTimeLine.setOnTouchListener(timeLineListeners);

		zoomInTimeLine.setOnScrollListener(timeLineListeners);
		zoomInTimeLine.setOnItemClickListener(timeLineListeners);
		zoomInTimeLine.setOnItemLongClickListener(timeLineListeners);
		zoomInTimeLine.setOnTouchListener(timeLineListeners);

	}
	private ItemListAdapter getAdapter(){
		return (ItemListAdapter) getTimeLine().getAdapter();
	}
	private CortexListView getTimeLine(){
		switch(getLevel()){
		case REGULAR_ZOOM:
			return regularTimeLine;
		case ZOOM_IN:
			return zoomInTimeLine;
		case ZOOM_OUT:
			return zoomOutTimeLine;
		default:
			return regularTimeLine;
		}
	}

	private void createAnimationFavorite(final VisitLink visitLink,ViewGroup group){
		final ImageView pointTime = (ImageView) group.findViewById(R.id.pointTime);
		final ImageView favorite = new ImageView(getContext());
		float y = group.getTop() + (group.getHeight()/2)-(pointTime.getHeight()/2);
		Animation animation;

		favorite.setImageDrawable(getResources().getDrawable(R.drawable.favorite_visit_link));
		RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
				ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
		params.topMargin = (int) y;
		params.addRule(RelativeLayout.CENTER_HORIZONTAL,RelativeLayout.TRUE);
		containerTimeLine.addView(favorite,params);

		if(!visitLink.isFavorite()){
			animation = AnimationUtils.loadAnimation(getContext(), R.anim.fade_in);
		}
		else{
			animation = AnimationUtils.loadAnimation(getContext(), R.anim.fade_out);
		}
		animation.setDuration(500);
		animation.setAnimationListener(new AnimationListener() {

			@Override
			public void onAnimationStart(Animation animation) {
				if(visitLink.isFavorite()){
					pointTime.setImageDrawable(getResources().getDrawable(R.drawable.point_time));
				}
			}

			@Override
			public void onAnimationRepeat(Animation animation) {
				// TODO Auto-generated method stub

			}

			@Override
			public void onAnimationEnd(Animation animation) {
				visitLink.setFavorite(!visitLink.isFavorite());
				pointTime.setImageDrawable(visitLink.isFavorite()?
						getResources().getDrawable(R.drawable.favorite_visit_link):
							getResources().getDrawable(R.drawable.point_time));

				containerTimeLine.removeView(favorite);
				notifyDataChanged();
			}
		});
		favorite.startAnimation(animation);
	}
	private void savePosition(){
		savedPosition = getTimeLine().getFirstVisiblePosition();
		View firstVisibleView = getTimeLine().getChildAt(0);
		savedListTop = (firstVisibleView == null) ? 0 : firstVisibleView.getTop();
	}
	private void restorePosition(){
		if (savedPosition >= 0) { //initialized to -1
			regularTimeLine.setSelectionFromTop(savedPosition, savedListTop);
			zoomOutTimeLine.setSelectionFromTop(savedPosition, savedListTop);
			zoomInTimeLine.setSelectionFromTop(savedPosition, savedListTop);

		}
	}
	public void setOnFinishedScrollListener(OnFinishedScrollListener onFinishedScrollListener) {
		this.onFinishedScrollListener = onFinishedScrollListener;
	}
	public void setOnClickVisitLink(OnClickVisitLink onClickVisitLink) {
		this.onClickVisitLink = onClickVisitLink;
	}
	public LEVEL_ZOOM getLevel() {
		if(level == null){
			level = LEVEL_ZOOM.REGULAR_ZOOM;
		}
		return level;
	}
	public void setLevel(LEVEL_ZOOM level){
		this.level = level;
		regularTimeLine.setAlpha(0.0f);
		zoomOutTimeLine.setAlpha(0.0f);
		zoomInTimeLine.setAlpha(0.0f);
		regularTimeLine.setVisibility(GONE);
		zoomOutTimeLine.setVisibility(GONE);
		zoomInTimeLine.setVisibility(GONE);
		switch(level){
		case REGULAR_ZOOM:
			regularTimeLine.setAlpha(1.0f);
			regularTimeLine.setVisibility(VISIBLE);
			line.setAlpha(1.0f);
			break;
		case ZOOM_IN:
			zoomInTimeLine.setAlpha(1.0f);
			zoomInTimeLine.setVisibility(VISIBLE);
			line.setAlpha(1.0f);
			break;
		case ZOOM_OUT:
			zoomOutTimeLine.setAlpha(1.0f);
			zoomOutTimeLine.setVisibility(VISIBLE);
			line.setAlpha(0.0f);
			break;
		default:
			break;

		}
		restorePosition();
		changeHeaderView(getTimeLine().getFirstVisiblePosition());
	}
	public void buildAdapter(List<Header> headers){
		ItemListAdapter zoomInAdapter = (ItemListAdapter) zoomInTimeLine.getAdapter();
		ItemListAdapter regularAdapter = (ItemListAdapter) regularTimeLine.getAdapter();
		ItemListAdapter zoomOutAdapter = (ItemListAdapter) zoomOutTimeLine.getAdapter();
		
		if(zoomInAdapter == null){
			// zoomIn
			zoomInAdapter = new ZoomInHistoryAdapter(getContext());
			zoomInTimeLine.setAdapter(zoomInAdapter);
		}
		zoomInAdapter.addItems(headers);

		if(regularAdapter == null){
			// regular zoom
			regularAdapter = new RegularZoomHistoryAdapter(getContext());
			regularTimeLine.setAdapter(regularAdapter);
		}
		regularAdapter.addItems(headers);

		if(zoomOutAdapter == null){
			// zoomOut
			zoomOutAdapter = new ZoomOutHistoryAdapter(getContext());
			zoomOutTimeLine.setAdapter(zoomOutAdapter);
		}
		zoomOutAdapter.addItems(headers);
		
		setLevel(getLevel());
//				adapter.setOnDragRowListener(onDragRowListener);
	}


	public void setOnDragVisitLinkListener(OnDragItemListener onDragRowListener) {
		this.onDragRowListener = onDragRowListener;
	}


	

	public void clear() {
		ItemListAdapter regularAdapter = (ItemListAdapter)regularTimeLine.getAdapter();
		ItemListAdapter zoomOutAdapter = (ItemListAdapter)zoomOutTimeLine.getAdapter();
		ItemListAdapter zoomInAdapter = (ItemListAdapter)zoomInTimeLine.getAdapter();

		if(regularAdapter != null){
			regularAdapter.clear();
		}
		if(zoomOutAdapter != null){
			zoomOutAdapter.clear();
		}
		if(zoomInAdapter != null){
			zoomInAdapter.clear();
		}
	}
	public void notifyDataChanged() {
		getTimeLine().invalidate();
		getAdapter().notifyDataSetInvalidated();
		getAdapter().notifyDataSetChanged();
	}
	private class TimeLineListeners 
	implements OnScrollListener,OnItemClickListener,OnItemLongClickListener,OnTouchListener{
		private float x = 0,x1 = 0,y = 0,y1 = 0;
		private int lastDistance;
		private float alphaShow,alphaGone;
		private CortexListView timeLineToShow,timeLineToGone;
		private LEVEL_ZOOM nextLevel;	
		private float distanceInPercent;
		private boolean isZoomOut;

		@Override
		public boolean onTouch(View v, MotionEvent event) {
			int distance;
			float maxDistance = Math.min(getWidth(), getHeight());
			float minDistance = 0;
			switch(event.getAction() & MotionEvent.ACTION_MASK){
			case MotionEvent.ACTION_POINTER_DOWN:
				isZoomMode = true;
				lastDistance = 0;
				alphaGone = 0;
				alphaShow = 0;
				timeLineToShow = null;
				timeLineToGone = null;
				lastDistance = getDistance(event);
				restorePosition();

				if(event.getPointerCount() > 1){
					distance = getDistance(event);
					distanceInPercent = (distance * 100.0f / maxDistance)/100.0f;
					isZoomOut = distanceInPercent > 0.5;

					if(isZoomOut && getLevel() != LEVEL_ZOOM.ZOOM_OUT){
						nextLevel = LEVEL_ZOOM.values()[level.ordinal() + 1];
					}
					else if(!isZoomOut && getLevel() != LEVEL_ZOOM.ZOOM_IN){
						nextLevel = LEVEL_ZOOM.values()[getLevel().ordinal() - 1];
					}
				}

				return false;
			case MotionEvent.ACTION_MOVE:
				if(isZoomMode && event.getPointerCount() > 1){
					distance = getDistance(event);
					distanceInPercent = (distance * 100.0f / maxDistance)/100.0f;


					if(isZoomOut){
						alphaShow = 1.0f-distanceInPercent;
						alphaGone = distanceInPercent;
						// zoom out
						switch(getLevel()){
						case REGULAR_ZOOM:
							// next level zoom = zoom out
							timeLineToShow = zoomOutTimeLine;
							timeLineToGone = regularTimeLine;
							line.setAlpha(alphaGone);
							break;
						case ZOOM_IN:
							// next level zoom = regular zoom
							timeLineToShow = regularTimeLine;
							timeLineToGone = zoomInTimeLine;
							break;
						case ZOOM_OUT:
						default:
							isZoomMode = false;
							break;
						}
					}
					else{
						// zoom in
						alphaShow = distanceInPercent;
						alphaGone = 1.0f-distanceInPercent;
						switch(getLevel()){
						case REGULAR_ZOOM:
							timeLineToShow = zoomInTimeLine;
							timeLineToGone = regularTimeLine;	
							line.setAlpha(alphaShow);
							break;
						case ZOOM_OUT:
							timeLineToShow = regularTimeLine;
							timeLineToGone = zoomOutTimeLine;
							line.setAlpha(alphaGone);
							break;
						case ZOOM_IN:
						default:
							isZoomMode = false;
							break;
						}
					}
					if(timeLineToShow != null && timeLineToGone != null){
						timeLineToShow.setVisibility(VISIBLE);
						timeLineToGone.setVisibility(VISIBLE);
						timeLineToShow.setAlpha(alphaShow);
						timeLineToGone.setAlpha(alphaGone);
					}
					lastDistance = distance;
				}
				return false;
			case MotionEvent.ACTION_UP:
			case MotionEvent.ACTION_CANCEL:
				boolean isClicked = isZoomMode;
				if(isZoomMode){
					if(isZoomOut && distanceInPercent > 0.5 ||
							!isZoomOut  && distanceInPercent < 0.5){
						nextLevel = getLevel();
					}
					setLevel(nextLevel);
					isZoomMode = false;
					nextLevel = null;
				}
				return isClicked;
			}
			return false;
		}
		private int getDistance(MotionEvent event){
			float distanceX,distanceY,distance;

			x = event.getX(0);
			y = event.getY(0);
			x1 = event.getX(1);
			y1 = event.getY(1);

			distanceX = Math.abs(x-x1);
			distanceY = Math.abs(y-y1);
			distance = Math.max(distanceX, distanceY);
			return (int) distance;
		}
		@Override
		public void onItemClick(AdapterView<?> adapterView, View view, int position,
				long id) {
			if(onClickVisitLink != null){
				Object obj = adapterView.getItemAtPosition(position);
				if(obj instanceof VisitLink){
					onClickVisitLink.visitLinkClicked((VisitLink) obj);
				}
			}
		}
		@Override
		public boolean onItemLongClick(AdapterView<?> adapterView, View view,
				int position, long id) {
			if(onClickVisitLink != null){
				ItemList itemList = (ItemList) adapterView.getItemAtPosition(position);
				if(!itemList.isHeader()){
					final VisitLink visitLink = (VisitLink)itemList;
					if(getLevel() != LEVEL_ZOOM.ZOOM_OUT){
						createAnimationFavorite(visitLink, (ViewGroup) view);
					}
					else{
						visitLink.setFavorite(!visitLink.isFavorite());
					}
					onClickVisitLink.visitLinkLongClicked(visitLink);
					return true;
				}
			}
			return false;
		}
		@Override
		public void onScrollStateChanged(AbsListView view, int scrollState) {
			if(isZoomMode){
				regularTimeLine.setStopScroll(true);
				zoomOutTimeLine.setStopScroll(true);
				zoomInTimeLine.setStopScroll(true);
				return;
			}
			if(scrollState == SCROLL_STATE_IDLE){
				savePosition();
				if((view.getLastVisiblePosition() == getAdapter().getCount()-1)){
					if(onFinishedScrollListener != null){	
						lastSeason = (SeasonQuerySearch) getAdapter().getHeaderByItem(view.getLastVisiblePosition());
						onFinishedScrollListener.finishedScroll((SeasonQuerySearch) lastSeason);
					}
				}
			}
		}

		@Override
		public void onScroll(AbsListView absListView, int firstVisibleItem,
				int visibleItemCount, int totalItemCount) {
			if(getAdapter() != null){
				SeasonQuerySearch season = (SeasonQuerySearch) getAdapter().getHeaderByItem(firstVisibleItem);
				Log.d(MessagesLog.APPLICATION,"onScroll");
				if(season != null){
//					if(lastSeason == null){
////						dateSeason.setText(dateFormater.format(season.getStartSeason()));
////						query.setTextWithUnderLine(season.getQuery());
////						dateQuery.setText(timeFormater.format(season.getStartSeason()));
//						
						changeHeaderView(firstVisibleItem);
						lastSeason = season;
						return;
					}
					if(!lastSeason.equals(season)){
////						Calendar currentCal = Calendar.getInstance();
////						Calendar previousCal = Calendar.getInstance();
////
////						currentCal.setTime(season.getStartSeason());
////						previousCal.setTime(lastSeason.getStartSeason());
////
////						if(currentCal.get(Calendar.DAY_OF_YEAR) != previousCal.get(Calendar.DAY_OF_YEAR)){
////							dateSeason.setText(dateFormater.format(season.getStartSeason()));
////						}
////
////						query.setTextWithUnderLine(season.getQuery());
////						dateQuery.setText(timeFormater.format(season.getStartSeason()));
//						
						changeHeaderView(firstVisibleItem);
					}
					lastSeason = season;
				}
//			}
		}
	}


	private void changeHeaderView(int position){
		
//		View lastHeader = containerHeader.getChildAt(0);
//		int width = LayoutParams.MATCH_PARENT;
//		int height = LayoutParams.WRAP_CONTENT;
//		if(lastHeader != null){
//			width = lastHeader.getLayoutParams().width;
//			height = lastHeader.getLayoutParams().height;
//			containerHeader.removeView(lastHeader);
//		}
//		int headerPosition = getAdapter().numberOfHeaderByItem(position);
//		View headerView = getAdapter().getHeaderView(headerPosition, null, null);
//
////		((ViewGroup)headerView).findViewById(R.id.containerDateSeason).setVisibility(VISIBLE);
//		LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(width, height);
//		headerView.setLayoutParams(params);
////		containerHeader.addView(headerView);
	}
	public interface OnClickVisitLink{
		void visitLinkClicked(VisitLink visitLink);
		void visitLinkLongClicked(VisitLink visitLink);
	}

	public interface OnFinishedScrollListener{
		void finishedScroll(SeasonQuerySearch season);
	}
	public enum LEVEL_ZOOM{
		ZOOM_IN,
		REGULAR_ZOOM,
		ZOOM_OUT
	}


}
